Skip to main content
L
Loopaloo
Buy Us a Coffee
All ToolsImage ProcessingAudio ProcessingVideo ProcessingDocument & TextPDF ToolsCSV & Data AnalysisConverters & EncodersWeb ToolsMath & ScienceGames
Guides & BlogAboutContact
Buy Us a Coffee
L
Loopaloo

Free online tools for developers, designers, and content creators. Your files are processed in your browser and are never uploaded - no accounts required. A few network utilities (like What's My IP and Currency Converter) call public APIs to do their job and say so on their pages.

support@loopaloo.com

Tool Categories

  • Image Tools
  • Audio Tools
  • Video Tools
  • Document & Text
  • PDF Tools
  • CSV & Data
  • Converters
  • Web Tools
  • Math & Science
  • Games

Company

  • About Us
  • Contact
  • Blog
  • FAQ

Legal

  • Privacy Policy
  • Terms of Service
  • Disclaimer

Support

Buy Us a Coffee

© 2026 Loopaloo. All rights reserved. Built with privacy in mind.

Privacy|Terms|Disclaimer
  1. Home
  2. CSV & Data Analysis
  3. CSV Row Filter
Add to favorites

CSV Row Filter

Filter rows with each condition stating its rule: a cell that is not a number does not match a comparison, and an empty cell is not a zero

Rows never leave your deviceMore csv & data analysisJump to full guide

Initializing in your browser…

You might also like

CSV Column Filter

Keep and reorder chosen columns, with the list built from the widest row so a field beyond the header is not dropped

CSV Search & Replace

Find and replace with both halves stated: what the pattern matches, and whether $1 and $& in the replacement are patterns or text

CSV Viewer & Editor

View, sort and edit a CSV, with an undo stack that goes back exactly one step and a parse report that tells a broken quote from a ragged row

A sample run

A price column holding a currency amount, a grouped thousand, an empty cell and a hex-looking product code, filtered on "is greater than 1000". Four of those five rows are decided by what the tool thinks a number is.

products.csv, filtered on price is greater than 1000

id,price
1,"$1,299.99"
2,999
3,
4,0x1F
5,"1,500"
What CSV Row Filter produces

Rows kept

1,$1,299.99
5,1,500

The rule this condition enforces:
"The cell reads as a number and is above the value. A cell that is not
 a number does not match, and an empty cell is not a zero."

Rows 1 and 5 are the two prices above a thousand. A filter built on Number() keeps neither of them, because Number("$1,299.99") and Number("1,500") are both NaN, and it keeps row 4 instead, because Number("0x1F") is 31. Row 3 is the one that matters most: an empty cell is not a zero, so it does not quietly satisfy a comparison against a positive number the way Number("") does.

About the CSV Row Filter

Keep the rows that match your conditions, with each condition’s rule written out on the page. A filter is only as good as what it means by "greater than 10" and "is a date", so this one says: a cell that is not a number does not match a numeric comparison, an empty cell is not a zero, and 29 February in a common year is not a date.

How to use

  1. 1Upload your CSV
  2. 2Add a group, then a condition: pick the column, the operator and the value
  3. 3Read the rule under the condition to check it means what you meant
  4. 4Combine conditions with AND or OR inside a group, and groups with AND or OR
  5. 5Download the matching rows

Key features

  • Twenty four operators, each with its rule written out on the page
  • Numbers read under a stated grammar, so 1,234 and $50 work and 0x1F and Infinity do not
  • Calendar-checked dates, including day-first dates the Date constructor refuses
  • Independent switches for case, spaces and accents, with case folded in the Unicode sense
  • A condition that cannot be evaluated reported with the reason, taking no part in the filter
  • Groups of conditions combined with AND or OR, saved, exported and imported

How it works

A filter is an acceptor, so the question that matters is which rows it keeps that it should not. Every operator here goes to a decider rather than a coercion.

**Numbers.** A cell is read as a number under a stated decimal grammar: sign, digits, one decimal separator, an optional exponent, and around it the decorations a spreadsheet adds, so 1,234, $50, 50% and (500) are all numbers. `0x1F`, `0b101`, `Infinity`, `NaN` and `1_000` are not, and neither is an empty cell or one holding a space. That last one matters more than it looks: `Number("")` is 0, which is how an empty cell comes to pass "less than 10".

**Dates.** A date is a real calendar date. A bare number is not one, 29 February in a common year is not one, and 31 April is not one. A day-first date like 15/01/2024 IS one, which the JavaScript Date constructor refuses outright.

**Text.** Comparison is exact by default: case, surrounding spaces and the spelling of an accented letter all count. Turn on the matching options and each is an independent switch, with case folded in the Unicode sense so the German sharp s matches ss.

**A condition that cannot be evaluated is not the same as a condition nothing matches.** A mistyped regular expression, a bound that is not a number, a missing second bound: each is reported with the reason and takes no part in the filter, rather than quietly hiding every row. And a condition you switch OFF takes no part at all, which is not the same as one that matches everything.

Conditions go in groups, each group joining its own with AND or OR, and the groups joined with AND or OR in turn. The whole arrangement can be saved, exported and imported.

Where this fits a data pipeline

  • Pulling out the rows that need attention

    Combine "is empty" on one column with a numeric threshold on another to find the records that are both incomplete and material.

  • Segmenting a dataset

    Group conditions so that region is one of a list AND either the value is above a threshold OR the date is recent.

  • Checking a suspicion about a column

    "is a number" and "is a date" tell you how many cells really are, under a definition you can read, rather than under whatever the browser guesses.

Tips & best practices

  • Read the sentence under each condition. It is the rule that condition actually enforces, generated from the same code that runs it.
  • If the result is empty and you expected rows, look for the amber panel: a condition that could not be evaluated is listed there rather than silently matching nothing.
  • For a numeric column with currency symbols or grouped thousands, use the numeric operators directly. They read those; you do not need to clean the column first.

Examples

  • Price over 1,000

    A column holding $1,299.99 and 999 filters correctly on "is greater than 1000". A comparison built on Number() reads the first as NaN and drops it.

  • Rows with a missing score

    "is empty" matches a cell holding nothing and a cell holding only spaces, and does not match a zero.

  • A pattern with a typo in it

    Filtering on the pattern [ reports "that is not a valid regular expression" and leaves every row in place, instead of showing an empty table with no explanation.

Frequently asked questions

Why did an empty cell match "less than 10"?

It does not here. That is what happens when a filter uses Number(), because Number("") is 0. A cell that is not a number does not match a numeric comparison at all.

Does it handle prices with currency symbols and thousands separators?

Yes. $1,299.99 is the number 1299.99, 50% is 0.5, and (500) is -500. Those are the numbers people have in spreadsheets.

Why is 0x1F not greater than 20?

Because it is a string in a CSV file, not a hexadecimal literal. Number() reads it as 31, which is a JavaScript convention rather than a data one.

I switched a condition off and everything matched. Why?

That was a bug and it is fixed. A disabled condition now takes no part at all; previously it evaluated to true, which inside an OR group made every row match.

My regular expression is wrong. What happens?

The page tells you, with the error from the pattern, and that condition takes no part in the filter. It does not silently match nothing.

Private by design

Rows and columns are parsed and transformed in memory in your browser. No record ever reaches a server.