Skip to main content

A Python package for parsing and evaluating boolean text queries

Project description

Boolean Query Parser

PyPI Downloads

▶ Try it live in your browser — no install needed, runs via WebAssembly

A lightweight, zero-dependency Python package for parsing and evaluating complex boolean text queries. Supports AND, OR, NOT operators, parentheses for nesting, and regular expression pattern matching — built entirely on the Python standard library.

Features

  • Zero external dependencies — uses only the Python standard library (re), so it installs instantly and adds no weight to your project
  • Boolean operators: AND, OR, NOT
  • Implicit AND: adjacent terms without an operator are treated as AND (e.g. python flask equals python AND flask)
  • Parentheses for grouping and complex nested expressions
  • Quoted strings for exact phrase matching ("exact phrase")
  • Regular expression pattern matching with support for:
    • Regular expression flags (i for case-insensitive, m for multiline, s for dotall, x for verbose)
    • Complex patterns including capture groups, lookaheads, and lookbehinds
    • Special character escaping
  • Simple, intuitive query syntax
  • Comprehensive error handling with clear messages

Installation

From PyPI

pip install boolean-query-parser

From Source

Clone the repository and install using pip:

git clone https://github.com/Piergiuseppe/boolean-query-parser.git
cd boolean-query-parser
pip install .

Usage

Basic Example

from boolean_query_parser import parse_query, apply_query

# Define some sample text data
documents = [
    "The quick brown fox jumps over the lazy dog",
    "Python is a programming language",
    "The Python programming language is powerful and easy to learn",
    "Regular expressions can be complex but useful"
]

# Parse a query
query = 'Python AND programming AND NOT complex'
parsed_query = parse_query(query)

# Apply the query to filter documents
matching_documents = [doc for doc in documents if apply_query(parsed_query, doc)]

# Print results
for doc in matching_documents:
    print(doc)

Output:

Python is a programming language
The Python programming language is powerful and easy to learn

Advanced Example with Nested Expressions

from boolean_query_parser import parse_query, apply_query

# Parse a complex query with parentheses and multiple operations
query = '(Python OR programming) AND (language OR easy) AND NOT (complex OR difficult)'
parsed_query = parse_query(query)

# Sample text data
documents = [
    "Python is a great language for beginners",
    "Programming can be complex and difficult at times",
    "Python makes programming tasks easy to accomplish",
    "This text has nothing relevant"
]

# Apply the query
for doc in documents:
    if apply_query(parsed_query, doc):
        print(f"Match: {doc}")
    else:
        print(f"No match: {doc}")

Using Regular Expressions

from boolean_query_parser import parse_query, apply_query

# Parse a query with regex patterns
query = '/py.*on/i AND NOT /difficult/'
parsed_query = parse_query(query)

documents = [
    "Python is easy to learn",
    "python programming is fun",
    "This is difficult Python code",
    "PyThOn is case-insensitive in this example"
]

# Apply the query
for doc in documents:
    if apply_query(parsed_query, doc):
        print(f"Match: {doc}")

Using Regular Expression Flags

from boolean_query_parser import parse_query, apply_query

# Case-insensitive matching with 'i' flag
query = '/python/i'
parsed_query = parse_query(query)
print(apply_query(parsed_query, "This contains PYTHON"))  # True

# Multiline matching with 'm' flag
multiline_text = "First line\nSecond line with python\nThird line"
query = '/^Second.*python$/m'
parsed_query = parse_query(query)
print(apply_query(parsed_query, multiline_text))  # True

# Dot-all mode with 's' flag (dot matches newlines)
text_with_newlines = "Start\nMiddle\nEnd"
query = '/Start.*End/s'
parsed_query = parse_query(query)
print(apply_query(parsed_query, text_with_newlines))  # True

Complex Regex Patterns

from boolean_query_parser import parse_query, apply_query

# Email validation with regex
email_pattern = '/([A-Za-z0-9]+[._-])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\\.[A-Za-z]{2,})/'
email_query = parse_query(email_pattern)

# HTML tag matching with capture groups and backreferences
html_pattern = '/\\<([a-z][a-z0-9]*)(\\s[^\\>]*)?\\>([^\\<]*)\\<\\/\\1\\>/i'
html_query = parse_query(html_pattern)

# Password validation with lookaheads
password_pattern = '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,}$/'
password_query = parse_query(password_pattern)

# Test them
print(apply_query(email_query, "Contact us at info@example.com"))  # True
print(apply_query(html_query, "<div>Content</div>"))  # True
print(apply_query(password_query, "Password123"))  # True

API Documentation

parse_query(query_str: str) -> Node

Parses a boolean query string into an abstract syntax tree (AST).

Parameters:

  • query_str (str): The boolean query string to parse.

Returns:

  • Node: The root node of the parsed AST.

Raises:

  • QueryError: If the query has invalid syntax or mismatched parentheses.

Query Syntax:

  • Boolean operators: AND, OR, NOT
  • Implicit AND: adjacent terms without an operator are treated as AND (e.g. python flask equals python AND flask)
  • Terms can be wrapped in quotes for exact matching: "exact phrase"
  • Regular expressions can be specified with forward slashes: /pattern/
  • Regular expressions can include flags: /pattern/i (i=case-insensitive, m=multiline, s=dotall, x=verbose)
  • Parentheses can be used for grouping expressions

apply_query(parsed_query: Node, text: Union[str, List[str]]) -> Union[bool, List[str]]

Applies a parsed query to text data and returns whether the text matches the query.

Parameters:

  • parsed_query (Node): The parsed query AST from parse_query.
  • text (Union[str, List[str]]): A single string to evaluate, or a list of strings to filter.

Returns:

  • If text is a str: bool — True if the text matches the query, False otherwise.
  • If text is a list: List[str] — the subset of strings that match the query.

Real-World Use Cases

Log Analysis

Parse through server logs to find specific error patterns:

from boolean_query_parser import parse_query, apply_query
import glob

# Query to find critical errors related to database but not connection timeouts
query = '(ERROR OR CRITICAL) AND database AND NOT "connection timeout"'
parsed_query = parse_query(query)

# Process log files
matching_logs = []
for log_file in glob.glob('/var/log/application/*.log'):
    with open(log_file, 'r') as f:
        for line in f:
            if apply_query(parsed_query, line):
                matching_logs.append(line.strip())

print(f"Found {len(matching_logs)} matching log entries")

Document Classification

Categorize documents based on their content:

from boolean_query_parser import parse_query, apply_query

# Define category queries
categories = {
    'finance': parse_query('(banking OR investment OR financial) AND NOT (gaming OR entertainment)'),
    'technology': parse_query('(programming OR software OR hardware OR "machine learning") AND NOT financial'),
    'health': parse_query('(medical OR health OR doctor OR patient) AND NOT (technology OR finance)')
}

# Function to classify a document
def classify_document(text):
    results = []
    for category, query in categories.items():
        if apply_query(query, text):
            results.append(category)
    return results or ['uncategorized']

Email Filtering example

Filter emails based on complex patterns:

from boolean_query_parser import parse_query, apply_query

# Query to find emails that:
# 1. Have attachments (mention .pdf, .doc, etc.)
# 2. Are not from known domains
# 3. Contain specific keywords in the subject
query = parse_query('(/\\.pdf/i OR /\\.doc/i OR /\\.docx/i) AND NOT /from:.*@(company\\.com|trusted\\.org)/ AND /subject:.*urgent/i')

# Apply to email bodies
def filter_suspicious_emails(emails):
    return [email for email in emails if apply_query(query, email)]

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

boolean_query_parser-1.0.3.tar.gz (23.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

boolean_query_parser-1.0.3-py3-none-any.whl (11.2 kB view details)

Uploaded Python 3

File details

Details for the file boolean_query_parser-1.0.3.tar.gz.

File metadata

  • Download URL: boolean_query_parser-1.0.3.tar.gz
  • Upload date:
  • Size: 23.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for boolean_query_parser-1.0.3.tar.gz
Algorithm Hash digest
SHA256 20d9fa8ae00fbbe01369534c792dd26bc5981d8090f45ee59f8d20864447c2c6
MD5 b3370c294be85036653963676aea2ff0
BLAKE2b-256 fe2ba05cda10f928733cf88a87c9263cc5439bc5e080458683516c02e4bbdbf7

See more details on using hashes here.

File details

Details for the file boolean_query_parser-1.0.3-py3-none-any.whl.

File metadata

File hashes

Hashes for boolean_query_parser-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 e677527e33e8641c9e9c3b521763e293a51b9ba19f027cb76c21ebfab7c21793
MD5 05b2fed6436fb0b97870aebf0136ae4a
BLAKE2b-256 ffd32fb58cf6f506bf4f2d56a7b511fbee2ef03dba7ace2a7628418ef451c5c1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page